#include "opencv_base.h"

#include<opencv2\opencv.hpp>   
#include<opencv2\highgui\highgui.hpp>

using namespace std;
using namespace cv;

int doOpencvbase1()
{
	//这些方式都是自己拥有独立的内存空间
	Mat img1(2, 2, CV_8UC3, Scalar(0, 0, 255));
	cout << img1 << endl;

	int sz[3] = { 2,2,2 };
	Mat img2(3, sz, CV_8UC1, Scalar(0, 0, 0));
	//cout << img2 << endl;

	Mat img5;
	img5.create(4, 4, CV_8UC3);
	cout << img5 << endl;

	Mat img6 = Mat::zeros(4, 4, CV_8UC3);
	cout << img6 << endl;

	Mat img7 = img6.clone();
	cout << img7 << endl;

	Mat img8;
	img6.copyTo(img8);
	cout << img8 << endl;

	//下面都是浅拷贝，指针指向同一个实例
	Mat img9 = img8;
	Mat img10(img8);

	waitKey(0);
	return 0;
}


int doOpencvbase2()
{
	Mat SrcPic = imread("test.jpg");
	imshow("Src Pic", SrcPic);
	Mat image;

	//将原始图转化为灰度图
	cvtColor(SrcPic, image, COLOR_BGR2GRAY);
	//Mat image = imread("test1.jpg", CV_LOAD_IMAGE_GRAYSCALE); //注意了，必须是载入灰度图
	if (image.empty())
	{
		cout << "read image failure" << endl;
		return -1;
	}

	// 全局二值化
	int th = 100;
	Mat global;
	threshold(image, global, th, 255, CV_THRESH_BINARY_INV);

	// 局部二值化
	int blockSize = 25;
	int constValue = 10;
	Mat local;
	adaptiveThreshold(image, local, 255, CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY_INV, blockSize, constValue);

	imshow("threshold", global);
	imshow("adaptiveThreshold", local);

	waitKey(0);
	return 0;
}


int doOpencvbase3()
{
	Mat SrcPic = imread("test.jpg");
	imshow("Src Pic", SrcPic);
	Mat element = getStructuringElement(MORPH_RECT, Size(15, 15)); //getStructuringElement函数返回的是指定形状和尺寸的结构元素
	Mat DstPic;
	erode(SrcPic, DstPic, element); //腐蚀操作
	imshow("erode", DstPic);
	waitKey();
	return 0;
}


int doOpencvbase4()
{
	Mat SrcPic = imread("test.jpg");
	imshow("Src Pic", SrcPic);
	Mat DstPic;
	blur(SrcPic, DstPic, Size(7, 7));// 均值滤波
	imshow("4", DstPic);
	waitKey();
	return 0;
}


int doOpencvbase5()
{
	Mat SrcPic = imread("test.jpg");
	imshow("Src Pic", SrcPic);
	Mat DstPic, edge, grayImage;

	//创建与src同类型和同大小的矩阵
	DstPic.create(SrcPic.size(), SrcPic.type());

	//将原始图转化为灰度图
	cvtColor(SrcPic, grayImage, COLOR_BGR2GRAY);
	imshow("gray", grayImage);

	//先使用3*3内核来降噪
	blur(grayImage, edge, Size(3, 3));

	//运行canny算子
	Canny(edge, edge, 3, 9, 3);

	imshow("Canny", edge);

	waitKey();
	return 0;
}



int doOpencvbase6()
{
	Mat img = imread("test.jpg");
	imshow("src", img);
	Mat dstImg;
	cvtColor(img, dstImg, COLOR_BGR2GRAY);//从宏名字就可以知道，是彩色图转换到灰度图
	imshow("gray", dstImg);

	waitKey(0);
	return 0;
}


int doOpencvbase7()
{
	//Mat的用法
	Mat m1(2, 2, CV_8UC3, Scalar(0, 0, 255)); //其中的宏的解释：CV_[位数][带符号与否][类型前缀]C[通道数]
	cout << m1 << endl;

	//或者,利用IplImage指针来初始化,将IplImage*转化为Mat
	IplImage* image = cvLoadImage("lena.jpg");
	Mat mat = cvarrToMat(image);

	//Mat转IplImage:
	IplImage img = cvIplImage(mat);

	//或者
	Mat m2;
	m2.create(4, 5, CV_8UC(2));


	//点的表示:Point
	Point p;
	p.x = 1; //x坐标
	p.y = 1; //y坐标

	//或者
	Point p2(1, 1);

	//颜色的表示：Scalar(b,g,r);注意不是rgb，注意对应关系
	Scalar(1, 1, 1);

	//尺寸的表示:Size
	Size(5, 5);// 宽度和高度都是5

	//矩形的表示：Rect，成员变量有x,y,width,height
	Rect r1(0, 0, 100, 60);
	Rect r2(10, 10, 100, 60);
	Rect r3 = r1 | r2; //两个矩形求交集
	Rect r4 = r1 & r2; //两个矩形求并集


	waitKey(0);
	return 0;
}


int doOpencvbase8()
{
	Mat img = imread("test.jpg");
	for (int i = 0; i < img.rows; i++)
	{
		uchar* data = img.ptr<uchar>(i);  //获取第i行地址
		for (int j = 0; j < img.cols; j++)
		{
			printf("%d\n", data[j]);
		}
	}

	waitKey(0);
	return 0;
}


int doOpencvbase9()
{
	Mat img = imread("test.jpg");
	imshow("src", img);
	Mat dst, gray;
	cvtColor(img, gray, CV_RGB2GRAY);
	imshow("gray", gray);
	equalizeHist(gray, dst);

	imshow("equalizeHist", dst);

	waitKey(0);
	return 0;
}
